]> git.neil.brown.name Git - wiggle.git/blob - load.c
Release 0.8
[wiggle.git] / load.c
1 /*
2  * wiggle - apply rejected patches
3  *
4  * Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
5  *
6  *
7  *    This program is free software; you can redistribute it and/or modify
8  *    it under the terms of the GNU General Public License as published by
9  *    the Free Software Foundation; either version 2 of the License, or
10  *    (at your option) any later version.
11  *
12  *    This program is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  *
17  *    You should have received a copy of the GNU General Public License
18  *    along with this program; if not, write to the Free Software
19  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  *    Author: Neil Brown
22  *    Email: <neilb@suse.de>
23  */
24
25 /*
26  * read in files
27  *
28  * Files are read in whole and stored in a
29  * struct stream {char*, len}
30  *
31  *
32  * loading the file "-" reads from stdin which might require
33  * reading into several buffers
34  */
35
36 #include        "wiggle.h"
37 #include        <sys/types.h>
38 #include        <sys/stat.h>
39 #include        <unistd.h>
40 #include        <fcntl.h>
41 #include        <malloc.h>
42
43 static void join_streams(struct stream list[], int cnt)
44 {
45         /* join all the streams in the list (upto body=NULL)
46          * into one by re-allocing list[0].body and copying
47          */
48         int len=0;
49         int i;
50         char *c;
51
52         for (i=0; i<cnt ; i++)
53                 len += list[i].len;
54
55         c = realloc(list[0].body, len);
56         if (c == NULL)
57                 die();
58
59         list[0].body = c;
60         c  += list[0].len;
61         list[0].len = len;
62         for (i=1; i<cnt; i++) {
63                 memcpy(c, list[i].body, list[i].len);
64                 c += list[i].len;
65                 list[i].len = 0;
66         }
67 }
68
69 static struct stream load_regular(int fd)
70 {
71         struct stat stb;
72         struct stream s;
73         fstat(fd, &stb);
74
75         s.len = stb.st_size;
76         s.body = malloc(s.len);
77         if (s.body) {
78                 if (read(fd, s.body, s.len) != s.len) {
79                         free(s.body);
80                         s.body = NULL;
81                 }
82         } else die();
83         return s;
84 }
85
86 static struct stream load_other(int fd)
87 {
88
89         struct stream list[10];
90         int i = 0;
91
92         while(1) {
93                 list[i].body = malloc(8192);
94                 if (!list[i].body)
95                         die();
96                 list[i].len = read(fd, list[i].body, 8192);
97                 if (list[i].len < 0)
98                         die();
99                 if (list[i].len == 0)
100                         break;
101                 i++;
102                 if (i == 10) {
103                         join_streams(list, i);
104                         i = 1;
105                 }
106         }
107         join_streams(list, i);
108         return list[0];
109 }
110
111 struct stream load_file(char *name)
112 {
113         struct stream s;
114         struct stat stb;
115         int fd;
116
117         s.body = NULL;
118         s.len = 0;
119         if (strcmp(name, "-")==0)
120                 fd = 0;
121         else {
122                 fd = open(name, O_RDONLY);
123                 if (fd <0)
124                         return s;
125         }
126
127         if (fstat(fd, &stb) == 0) {
128
129                 if (S_ISREG(stb.st_mode))
130                         s = load_regular(fd);
131                 else
132                         s = load_other(fd);
133         }
134         close(fd);
135         return s;
136 }
137